﻿using Cinch;
using FR.SAFTAnalyser.Model;
using FR.SAFTAnalyser.ViewModels.Pane;
using MEFedMVVM.Common;
using OfficeOpenXml;
using OfficeOpenXml.Table;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FR.SAFTAnalyser.ViewModels
{
    public class PaymentViewModel : DocumentPartViewModel
    {
        public PaymentViewModel(SourceDocumentsPaymentsPayment payment)
            : base("Recibos")
        {
            if (!Designer.IsInDesignMode)
            {
                Mediator.Instance.Register(this);

                this.CurrentPayment = payment;
                GetTaxResume();

                this.DoOpenExcelCommand = new SimpleCommand<object, object>(CanOpenExcel, OpenExcel);
            }
        }

        internal override void ResetSaftFile()
        {
            this.CurrentPayment = null;
            this.CurrentPaymentLines = null;
            this.Resumo = null;
        }

        SourceDocumentsPaymentsPayment currentPayment;
        public SourceDocumentsPaymentsPayment CurrentPayment
        {
            get { return currentPayment; }
            set
            {
                currentPayment = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<PaymentViewModel>(x => x.CurrentPayment));

                if (SAFTAnalyser.SAFT.SaftAnalyser.Instance.SaftFile != null && SAFTAnalyser.SAFT.SaftAnalyser.Instance.SaftFile.MasterFiles != null && SAFTAnalyser.SAFT.SaftAnalyser.Instance.SaftFile.MasterFiles.Customer != null)
                    PaymentCustomer = SAFTAnalyser.SAFT.SaftAnalyser.Instance.SaftFile.MasterFiles.Customer.Where(c => c.CustomerID.Equals(currentPayment.CustomerID, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

                CurrentPaymentLines = new ObservableCollection<SourceDocumentsPaymentsPaymentLine>(currentPayment.Line);
            }
        }

        ObservableCollection<SourceDocumentsPaymentsPaymentLine> currentPaymentLines;
        public ObservableCollection<SourceDocumentsPaymentsPaymentLine> CurrentPaymentLines
        {
            get { return currentPaymentLines; }
            set
            {
                currentPaymentLines = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<PaymentViewModel>(x => x.CurrentPaymentLines));
            }
        }

        Customer paymentCustomer;
        public Customer PaymentCustomer
        {
            get { return paymentCustomer; }
            set
            {
                paymentCustomer = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<PaymentViewModel>(x => x.PaymentCustomer));
            }
        }

        ResumoIva[] resumo;
        public ResumoIva[] Resumo
        {
            get { return resumo; }
            set
            {
                resumo = value;
                NotifyPropertyChanged(ObservableHelper.CreateArgs<PaymentViewModel>(x => x.Resumo));
            }
        }

        private void GetTaxResume()
        {
            this.Resumo =
                (from l in this.CurrentPaymentLines
                 group l by new { l.Tax.TaxCode, l.Tax.Item } into g
                 select new ResumoIva
                 {
                     Codigo = g.Key.TaxCode,
                     Taxa = (g.Key.Item * 0.01m).ToString("p"),
                     Valor = g.Sum(linha => linha.Item * linha.Tax.Item * 0.01m),
                     Incidencia = g.Sum(linha => linha.Item)
                 }).ToArray();
        }

        #region Commands

        public Cinch.SimpleCommand<object, object> DoOpenExcelCommand { get; set; }

        private void OpenExcel(object args)
        {
            OpenPaymentInExcel(this.CurrentPayment, this.CurrentPaymentLines.ToArray());
        }

        internal bool CanOpenExcel(object args)
        {
            return this.CurrentPaymentLines != null && this.CurrentPaymentLines.Count > 0;
        }

        #endregion

        internal static void OpenPaymentInExcel(SourceDocumentsPaymentsPayment CurrentPayment, SourceDocumentsPaymentsPaymentLine[] lines)
        {
            if (CurrentPayment != null)
            {
                DataTable dtinvoice = new DataTable("Payment");
                dtinvoice.Columns.Add("PaymentRefNo", typeof(string));
                dtinvoice.Columns.Add("Estado", typeof(string));
                dtinvoice.Columns.Add("Data documento", typeof(DateTime));
                dtinvoice.Columns.Add("Data sistema", typeof(DateTime));
                dtinvoice.Columns.Add("Total s/ IVA", typeof(decimal));
                dtinvoice.Columns.Add("Total", typeof(decimal));
                dtinvoice.Columns.Add("Total imposto", typeof(decimal));
                dtinvoice.Columns.Add("Cliente", typeof(string));
                dtinvoice.Columns.Add("Periodo", typeof(int));
                dtinvoice.Columns.Add("Transacção", typeof(string));

                dtinvoice.Rows.Add(
                    CurrentPayment.PaymentRefNo,
                    CurrentPayment.DocumentStatus.PaymentStatus.ToString(),
                    CurrentPayment.DocumentStatus.PaymentStatusDate,
                    CurrentPayment.SystemEntryDate,
                    CurrentPayment.DocumentTotals.NetTotal,
                    CurrentPayment.DocumentTotals.GrossTotal,
                    CurrentPayment.DocumentTotals.TaxPayable,
                    CurrentPayment.CustomerID,
                    Int32.Parse(CurrentPayment.Period),
                    CurrentPayment.TransactionID);

                ExcelPackage pck = new ExcelPackage();
                var wsEnum = pck.Workbook.Worksheets.Add("SAFT Payment");
                wsEnum.Cells["C2"].Style.Numberformat.Format = "yyyy-MM-dd";
                wsEnum.Cells["D2"].Style.Numberformat.Format = "yyyy-MM-dd hh:mm:ss";

                wsEnum.Cells["E2"].Style.Numberformat.Format = @"#,##0.00";
                wsEnum.Cells["F2"].Style.Numberformat.Format = @"#,##0.00";
                wsEnum.Cells["G2"].Style.Numberformat.Format = @"#,##0.00";
                //Load the collection starting from cell A1...
                wsEnum.Cells["A1"].LoadFromDataTable(dtinvoice, true, TableStyles.Medium9);
                wsEnum.Cells[wsEnum.Dimension.Address].AutoFitColumns();

                if (lines != null)
                {
                    int row = 2;
                    var wsEnumLines = pck.Workbook.Worksheets.Add("SAFT Payment Lines");
                    wsEnumLines.Cells[1, 1].Value = "Line Number";
                    wsEnumLines.Cells[1, 2].Value = "Value";
                    wsEnumLines.Cells[1, 3].Value = "Operation";
                    wsEnumLines.Cells[1, 4].Value = "Settlement Amount";
                    wsEnumLines.Cells[1, 5].Value = "Tax";
                    wsEnumLines.Cells[1, 6].Value = "Tax Exemption Reason";
                    wsEnumLines.Cells[1, 7].Value = "Description";
                    wsEnumLines.Cells[1, 8].Value = "Invoice Date";
                    wsEnumLines.Cells[1, 9].Value = "Originating ON";
                    wsEnumLines.Cells[1, 10].Value = "DocNumber";

                    foreach (var line in lines)
                    {
                        wsEnumLines.Row(row).OutlineLevel = 0;

                        wsEnumLines.Cells[row, 1].Value = line.LineNumber;
                        wsEnumLines.Cells[row, 2].Value = line.Item;
                        wsEnumLines.Cells[row, 3].Value = line.ItemElementName.ToString();
                        wsEnumLines.Cells[row, 4].Value = line.SettlementAmount;
                        wsEnumLines.Cells[row, 5].Value = line.Tax.Item;
                        wsEnumLines.Cells[row, 6].Value = line.TaxExemptionReason;
                        wsEnumLines.Cells[row, 10].Value = line.DocNo;

                        foreach (var documentID in line.SourceDocumentID)
                        {
                            row++;
                            wsEnumLines.Row(row).OutlineLevel = 1;
                            wsEnumLines.Cells[row, 7].Value = documentID.Description;
                            wsEnumLines.Cells[row, 8].Value = documentID.InvoiceDate;
                            wsEnumLines.Cells[row, 9].Value = documentID.OriginatingON;
                        }
                        row++;
                    }

                    wsEnumLines.Cells[string.Format("H2:H{0}", row + 1)].Style.Numberformat.Format = "yyyy-MM-dd";

                    wsEnumLines.Cells[string.Format("B{0}", row + 2)].Formula = string.Format("SUM(B2:B{0})", row + 1);
                    wsEnumLines.Cells[string.Format("C{0}", row + 2)].Formula = string.Format("SUM(C2:C{0})", row + 1);
                    wsEnumLines.Cells[string.Format("E{0}", row + 2)].Formula = string.Format("SUM(E2:E{0})", row + 1);

                    wsEnumLines.Tables.Add(new ExcelAddressBase(1, 1, row - 1, 9), "PaymentLines");
                    wsEnumLines.Tables["PaymentLines"].TableStyle = TableStyles.Medium9;

                    wsEnumLines.OutLineSummaryBelow = false;
                    wsEnumLines.Cells[wsEnumLines.Dimension.Address].AutoFitColumns();
                }

                //...and save
                var fi = new FileInfo(Path.GetTempPath() + Path.GetRandomFileName() + ".xlsx");

                pck.SaveAs(fi);

                Process.Start(fi.FullName);
            }
        }
    }
}
